Шаг 5 - Добавление событий.

Теперь Вы добавите ClickIn и ClickOut событие к вашему элементу управления.

Вы будете вызывать ClickIn событие если пользователь нажимает внутри многоугольника и вызывать ClickOut если пользователь нажимает снаружи.

Когда Вы создавали полный элемент управления Вы выбрали флажок Support Connection Point. Это привело к созданию интерфейса IPolyCtlEvents в вашем .idl файле. Обратите внимание что имя интерфейса начинается с символом подчеркивания. Это правило чтобы указать что интерфейс - внутренний интерфейс. Таким образом программы которые позволяют Вам просматривать объекты COM, могут выбирать, какой интерфейс показывать пользователю. Также обратите внимание в .idl файле, что Support Connection Points добавил строку для указания что IPolyCtlEvents - заданный по умолчанию исходный интерфейс. Исходный атрибут указывает что элемент управления - источник уведомлений и что он вызовет этот интерфейс у контейнера.

Теперь Вы должны добавить ClickIn и ClickOut методы к интерфейсу IPolyCtlEvents:
1. Щелкайте правой кнопкой на IPolyCtlEvents в ClassView и выбераете Add Method из меню.
2. Выберите тип Возврата void.
3. Напечатайте ClickIn в поле Method Name.
4. Введите [in] long x, [in] long y в поле параметров.
5. Нажмите OK.

Проверьте .idl файл чтобы видеть код который был добавлен к IPolyCtlEvents. Затем повторите ту же самую процедуру чтобы определить ClickOut метод с теми же самыми параметрами и типом возврата. IPolyCtlEvents dispinterface в вашем .idl файле должен теперь выглядеть следующим образом:

dispinterface _IPolyCtlEvents
{
   properties:
   methods:
   [id(1), helpstring("method ClickIn")] void ClickIn([in]long x, [in] long y);
   [id(2), helpstring("method ClickOut")] void ClickOut([in] long x, [in] long y);
};

ClickIn и ClickOut методы берут x и у координаты нажатой точки как параметры.

Теперь нужно сгенерировать вашу библиотеку типов. Чтобы сделать это Вы можете или собрать ваш проект или щелкнуть правой кнопкой мыши на .idl файл в FileView и выбрать Compile Polygon.idl. Это создаст файл Polygon.tlb который является вашей библиотекой типов.

Затем выполните интерфейс точки соединения и интерфейс контейнера точки соединения для вашего элемента управления. (В COM события выполнены через механизм точек соединения). Чтобы получать события от объекта COM, контейнер устанавливает консультативное соединение с точкой соединения которую объект COM использует. Так как объект COM может иметь много точек соединения, объект COM также осуществляет интерфейс контейнера точки соединения. Через этот интерфейс контейнер может определять, как точки соединения поддерживаются. Интерфейс который осуществляет точку соединения называется IConnectionPoint а интерфейс который осуществляет контейнер точки соединения называется IConnectionPointContainer.

Чтобы применять IConnectionPoint используйте ClassView для обращения к мастеру точки соединения. Этот мастер генерирует интерфейс IConnectionPoint читая вашу библиотеку типов и выполняется для каждого события, которое может быть вызвано.

Чтобы запустить мастера выполните следующие шаги:
1. Идите в ClassView (в меню View нажмите Workspace, чтобы увидеть ClassView).
2. Щелчок правой кнопкой на классе реализации вашего элемента управления, в данном случае CPolyCtl.
3. В контекстном меню, выберите Implement Connection Point...
4. Выберите _PolyEvents из списка Interfaces, затем нажмите OK и класс для точки соединения будет сгенерирован, в данном случае CProxy_IPolyCtlEvents.

6_1.gif (4733 b)

Если Вы посмотрите сгенерированный PolygonCP.h файл в FileView, Вы увидите что это класс с именем CProxy_PolyCtlEvents порожден от IConnectionPointImpl. PolygonCP.h также определяет два метода Fire_ClickIn и Fire_ClickOut которые берут два параметра. Эти методы Вы вызываете когда хотите сгенерировать событие из вашего элемента управления.

Мастер также добавил CProxy_PolyEvents и IConnectionPointContainerImpl к множественному списку наследования вашего элемента управления. Мастер также изменил IConnectionPointContainer добавляя соответствующие входы к карте COM.

Вы закончили создавать код для поддержки событий. Теперь нужно добавить код к вызову события в соответствующий момент. Не забудьте, Вы вызываете ClickIn или ClickOut событие когда пользователь нажимает левую кнопку мыши в элементе управления. Чтобы выяснять, когда пользователь нажимает кнопку, сначала добавляем обработчик для WM_LBUTTONDOWN сообщения. В ClassView правый щелчок на классе CPolyCtl и выбирам Add Windows Message Handler... из контекстного меню. Затем выберите WM_LBUTTONDOWN из списка слева и нажмите кнопку Add Handler. Нажмите OK.

Далее добавьте новый код к функции OnLButtonDown в PolyCtl.h (удалите любой код помещенный мастером) так, чтобы OnLButtonDown теперь выглядела следующим образом

LRESULT CPolyCtl::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
   HRGN hRgn;
   WORD xPos = LOWORD(lParam);  // horizontal position of cursor
   WORD yPos = HIWORD(lParam);  // vertical position of cursor

   CalcPoints(m_rcPos);

   // Create a region from our list of points
   hRgn = CreatePolygonRgn(&m_arrPoint[0], m_nSides, WINDING);

   // If the clicked point is in our polygon then fire the ClickIn
   //  event otherwise we fire the ClickOut event
   if (PtInRegion(hRgn, xPos, yPos))
      Fire_ClickIn(xPos, yPos);
   else
      Fire_ClickOut(xPos, yPos);

   // Delete the region that we created
   DeleteObject(hRgn);
   return 0;
}

Так как Вы уже вычислили точки многоугольника в функции OnDraw, используйте их в OnLButtonDown чтобы создать область. Затем используйте PtInRegion функцию API чтобы определить, находиться нажатая точка внутри многоугольника или нет.

UMsg параметр - ID обрабатываемого сообщения Windows. Это позволяет Вам иметь одну функцию которая обрабатывает диапазон сообщений. wParam и lParam - стандартные значения для обрабатываемого сообщения. Параметр bHandled позволяет Вам определять, обрабатывала ли функция сообщение или нет. По умолчанию, значение установлено к TRUE чтобы указать что функция обработала сообщение, но Вы можете устанавливать ее и к FALSE. Установка в FALSE заставит ATL продолжать искать другую функцию обработчика сообщения чтобы послать сообщение.

Теперь проверьте ваши события. Формируйте элемент управления и запустите ActiveX Control Test Container снова. На сей раз просмотрите окно регистрации событий. Чтобы направлять события в окно вывода выберите Logging из меню Options и выберите Log to output window. Теперь вставьте элемент управления и пробуйте щелкать в окне. Обратите внимание что ClickIn вызывается если Вы нажимаете внутри заполненного многоугольника, а ClickOut вызывается когда Вы нажимаете вне его.

Hosted by uCoz